﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices; 
using UnityEngine;
using UnityEngine.Audio;

public class MessageCompent : BaseCompent {
	
//	[DllImport("zlibnet")]  
//	private static extern SVZip add( int x, int y );  
//

	private static UIPanel panel;
	private static UISprite messageBox;
	private static UISprite sendMsgButton;
	private static UIInput input;
	private static List<UISprite> messageBoxs;
	private static List<UISprite> playRecords; //播放声音时显示的图片
	private static UIButton audioButton;
	private static UISprite record;
	private static AudioSource audioMgr;
	private static AudioSource textMessageSource;


	//录音部分
	private static bool isCancel = false;
	private static int touchY = 0;
	private static int duration = 0; //音量监听
	private static AudioClip clip;  
	//通常的无损音质的采样率是44100，即每秒音频用44100个float数据表示，但是语音只需8000（通常移动电话是8000）就够了  
	//不然音频数据太大，不利于传输和存储  
	public const int SamplingRate = 8000;  

	public static List<string> msgList = new List<string>(){
		"哎呀，七十岁大爷出牌都比你快",
		"唉，你慢慢配牌，我去海边吹下风",
		"急什么，让我想想怎么打",
		"急急急，赶着去投胎",
		"这么久没见了，最近在忙什么",
		"来来来，决战到天亮",
		"你牌玩得这么好，你爸妈知道嘛",
		"我是神枪手，打枪本领强",
		"今天忘记洗手了",
		"颤抖把，这把要全垒打",
		"不好意思，我接个电话",
		"我有事先走了，下次再玩吧"
	};

	//初始化
	public static void MessageInit(UIPanel messagePanel,List<UISprite> messageBoxs,
		List<UISprite> playRecords,AudioSource audioSource,AudioSource textMessageSource){

		MessageCompent.panel = messagePanel;
		MessageCompent.messageBoxs = messageBoxs;

		UISprite button = GetGameObjectByName<UISprite> (messagePanel.gameObject, "Message Button");
		UIEventListener.Get (button.gameObject).onClick += IsShow;

		MessageCompent.playRecords = playRecords;
		MessageCompent.audioMgr = audioSource;
		MessageCompent.textMessageSource = textMessageSource;
		MessageCompent.messageBox = GetGameObjectByName<UISprite> (messagePanel.gameObject, "Message Background");
		MessageCompent.sendMsgButton = GetGameObjectByName<UISprite> (messagePanel.gameObject, "Send Button");
		MessageCompent.input = GetGameObjectByName<UIInput> (messagePanel.gameObject, "Input Field");
		MessageCompent.audioButton = GetGameObjectByName<UIButton> (messagePanel.gameObject, "Audio Button");
		MessageCompent.record = GetGameObjectByName<UISprite> (messagePanel.gameObject, "Record");

		UIEventListener.Get (GetGameObjectByName<UISprite> (messagePanel.gameObject, "Send Button").gameObject).onClick += SendMessage;

		UISprite grid = GetGameObjectByName<UISprite> (messagePanel.gameObject, "Grid");
		if (grid.transform.childCount == 0) {
			for (int i = 0; i < msgList.Count; i++) {

				GameObject item = NGUITools.AddChild(grid.gameObject,(GameObject)(Resources.Load("Msg Item")));
				UILabel label = GetGameObjectByName<UILabel> (item, "Label");
				label.text = msgList[i];
				BoxCollider boxcollider = label.gameObject.AddComponent<BoxCollider> ();
				boxcollider.size = new Vector3 (2600, 300);

				UIEventListener.Get (label.gameObject).onClick += SendMessage;
			}
			grid.GetComponent<UIGrid>().repositionNow = true;

			UIEventListener.Get (MessageCompent.audioButton.gameObject).Clear ();
			UIEventListener.Get (MessageCompent.audioButton.gameObject).onPress += Record;
			UIEventListener.Get (MessageCompent.audioButton.gameObject).onDragStart += Drag;
			UIEventListener.Get (MessageCompent.audioButton.gameObject).onDrag += DragOn;
		}
	}

	private static void Drag(GameObject gameObject){
		Debug.Log (Input.mousePosition);
		touchY = (int)Input.mousePosition.y;
	}

	private static void DragOn(GameObject gameObject,Vector2 v){
		if (Input.mousePosition.y - touchY > 100) {
			isCancel = true;
			record.spriteName = "Record_Cancel";
		}
	}

	public static void Update(){
		duration++;
		if (duration > 30 && Microphone.IsRecording(null) && !isCancel) {
			duration = 0;
			// 采样数
			int sampleSize = 128;
			float[] samples = new float[sampleSize];
			int startPosition = Microphone.GetPosition(null) - (sampleSize);
			if (startPosition < 0) {
				startPosition = 0;
			}
			// 得到数据
			clip.GetData(samples, startPosition);

			// Getting a peak on the last 128 samples
			float levelMax = 0;
			for (int i = 0; i < sampleSize; ++i)
			{
				float wavePeak = samples[i];
				if (levelMax < wavePeak)
					levelMax = wavePeak;
			}

			float voice = levelMax * 100;
			record.spriteName = "Record_1";
			if (voice > 2f) {
				record.spriteName = "Record_2";
			} 
			if (voice > 8f) {
				record.spriteName = "Record_3";
			}
			if (voice > 14f) {
				record.spriteName = "Record_4";
			} 
		}
	}

	public static void HandTextMessage(string msg){
		JSONObject json = new JSONObject (msg);
		for (int i = 0; i < Main.room.players.Count; i++) {
			if (Main.room.players [i].id == json ["player_id"].str) {
				UISprite sprite = messageBoxs[i];
				UILabel label = GetGameObjectByName<UILabel> (sprite.gameObject, "Label");
				sprite.gameObject.SetActive (true);
				label.text = json ["msg"].str;

				EffectUtil.playMsgVoice (json ["msg"].str,textMessageSource);

				panel.StartCoroutine(DelayToInvoke.DelayToInvokeDo(() =>
					{
						sprite.gameObject.SetActive(false);
					},3f));
				return;
			}
		}
	}

	public static void handVoiceMessage(string msg){
		JSONObject json = new JSONObject (msg);
		if (json ["length"] == null) {
			json.AddField ("length", 2);
		}

		byte[] bytes = Utils.GetBytes (json ["voice"].str);
		if (json ["player_id"].str != Main.user.id) {
			audioMgr.clip = GetClip (bytes);
			audioMgr.volume = 1.0f;
			audioMgr.Play ();
		}

		Debug.Log ("播放图片显示时长:"+json["length"].str);

		float dur = float.Parse (json["length"].str);

		for (int i = 0; i < Main.room.players.Count; i++) {
			Debug.Log ("i:"+i);
			if (Main.room.players [i].id == json ["player_id"].str) {
				UISprite playRecord = playRecords [i];
				playRecord.gameObject.SetActive (true);
				playRecord.StartCoroutine(DelayToInvoke.DelayToInvokeDo(() =>
					{
						playRecord.gameObject.SetActive(false);
					}, dur));
			}
		}
	}

	private static void IsShow(GameObject gameObject){
		EffectUtil.DianJi();
		messageBox.gameObject.SetActive (!messageBox.gameObject.activeInHierarchy);
	}

	//发送消息
	private static void SendMessage(GameObject gameObject){
		EffectUtil.DianJi();
		if (gameObject.GetComponent<UILabel> () != null) {
			API.SendTextMessage (gameObject.GetComponent<UILabel> ().text);
		} else {
			API.SendTextMessage (input.value);
		}
		input.value = "";
		IsShow (MessageCompent.messageBox.gameObject);
	}

	private static void Record(GameObject gameObject,bool state){
		//改变界面 
		messageBox.gameObject.SetActive(false);
		MessageCompent.record.gameObject.SetActive (state);
		record.spriteName = "Record_1";

		if(state){//按钮按下开始录音  
			Microphone.End(null);//这句可以不需要，但是在开始录音以前调用一次是好习惯  
			clip = Microphone.Start(null,true,5,SamplingRate);  
		}else{//按钮弹起结束录音  
			float audioLength;//录音的长度，单位为秒，ui上可能需要显示  
			int lastPos = Microphone.GetPosition(null);  
			Microphone.End(null);//此时录音结束，clip已可以播放了
			audioLength = lastPos/SamplingRate;//录音时长

			if(audioLength<0.5f)return;//录音小于1秒就不处理了
			Play (clip,audioLength);
		}  
	}


	private static void Play(AudioClip clip,float audioLength){
		//去除无效时长
//		int vaildLength = (int)(audioLength*SamplingRate*20);
		byte[] bytes = GetData(clip);
//		byte[] newBytes = new byte[vaildLength];
//		for (int i = 0; i < vaildLength; i++) {
//			newBytes [i] = bytes [i];
//		}

		string str = Utils.ToHexString (bytes);
		Debug.Log ("录音时长："+audioLength);
		if (!isCancel) {
			API.SendAudio (str,audioLength);
		}
		isCancel = false;


		audioMgr.mute = false;
		audioMgr.clip = clip;
		audioMgr.volume = 1f;
		audioMgr.Play ();
	}


	public static byte[] GetData(AudioClip clip)
	{
		float[] data = new float[clip.samples * clip.channels];

		clip.GetData(data, 0);

		byte[] bytes = new byte[data.Length * 4];
		Buffer.BlockCopy(data, 0, bytes, 0, bytes.Length);


		return bytes;
	}

	public static AudioClip GetClip( byte[] bytes)
	{
		float[] data = new float[bytes.Length / 4];
		try{
			Buffer.BlockCopy(bytes, 0, data, 0, bytes.Length);
		}catch(Exception e){
			Debug.Log ("获取音频出错："+e.Message);
		}

		AudioClip audioClip = AudioClip.Create("testSound", data.Length, 1, SamplingRate, false, false);
		audioClip.SetData(data, 0);
		return audioClip;
	}

}
